package uk.ac.staffs.student.autopilot;

import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.PrintStream;
import java.util.TooManyListenersException;

/**
 * Mocks the serial port event listener interface by providing packet data as
 * expected from the HCI serial device
 * 
 * @author pgoudman
 * 
 */
public class SerialPortMock implements Runnable {

    /**
     * Read data from a file.
     */
    private File dateInputFile;
    private SerialPortEventListener listener;
    /**
     * Buffered input stream from the port
     */
    private InputStream input;
    /**
     * The output stream to the port
     */
    private PrintStream out;
    private BufferedReader in;
    private OutputStream output;
    private SerialPort serialPort;
    /**
     * Test data TODO: Read in from a file containing test data
     */
    private static final String UIV_DATA[] = {
            "[1,117,-93,-20,4]", // Windows
            "[1,18,-22,-11,-15]", // Windows
            "[1,23,-18,-13,-8]", // Windows
            "[1,12,-9,-9,-6] [1,12,-9,-9,-6]", // Windows
            "[1,24,-19,-13,-8]", // Windows
            "[2,0,0,123,123]",
            "[4,1,0]", // Ready to fly packet
            "[2,0,-41,123,82]", "[2,41,-82,165,124],", "[1,24,-19,-13,-8]",
            "[2,41,-41,82,82]", "[2,0,-41,123,82]", "[1,23,-18,-13,-8]  ",
            "[2,0,-82,165,83]", "[1,12,-9,-9,-6] \n[1,12,-9,-9,-6]",
            "[2,0,-82,165,83]", "[1,24,-19,-13,-8]" };

    @Override
    public void run() {
        final String file = "accel.data";
        final byte[] fileArray;
        // fileArray = File.readAllBytes(file);
        int gyroCtr = 0;
        try {
            while (!Thread.interrupted()) {

                if (gyroCtr >= UIV_DATA.length) {
                    gyroCtr = 0;
                }
                out.println(UIV_DATA[gyroCtr++]);
                out.flush();
                final SerialPortEvent anEvent = new SerialPortEvent(serialPort,
                        SerialPortEvent.DATA_AVAILABLE, true, true);
                listener.serialEvent(anEvent);

                Thread.sleep(2000L);

            }
        } catch (final InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    public SerialPortMock(final SerialPortEventListener listener)
            throws IOException {
        serialPort = new SerialPort() {

            @Override
            public void setOutputBufferSize(final int arg0) {
                // TODO Auto-generated method stub

            }

            @Override
            public void setInputBufferSize(final int arg0) {
                // TODO Auto-generated method stub

            }

            @Override
            public boolean isReceiveTimeoutEnabled() {
                // TODO Auto-generated method stub
                return false;
            }

            @Override
            public boolean isReceiveThresholdEnabled() {
                // TODO Auto-generated method stub
                return false;
            }

            @Override
            public boolean isReceiveFramingEnabled() {
                // TODO Auto-generated method stub
                return false;
            }

            @Override
            public int getReceiveTimeout() {
                // TODO Auto-generated method stub
                return 0;
            }

            @Override
            public int getReceiveThreshold() {
                // TODO Auto-generated method stub
                return 0;
            }

            @Override
            public int getReceiveFramingByte() {
                // TODO Auto-generated method stub
                return 0;
            }

            @Override
            public OutputStream getOutputStream() throws IOException {
                // TODO Auto-generated method stub
                return null;
            }

            @Override
            public int getOutputBufferSize() {
                // TODO Auto-generated method stub
                return 0;
            }

            @Override
            public InputStream getInputStream() throws IOException {
                // TODO Auto-generated method stub
                return null;
            }

            @Override
            public int getInputBufferSize() {
                // TODO Auto-generated method stub
                return 0;
            }

            @Override
            public void enableReceiveTimeout(final int arg0)
                    throws UnsupportedCommOperationException {
                // TODO Auto-generated method stub

            }

            @Override
            public void enableReceiveThreshold(final int arg0)
                    throws UnsupportedCommOperationException {
                // TODO Auto-generated method stub

            }

            @Override
            public void enableReceiveFraming(final int arg0)
                    throws UnsupportedCommOperationException {
                // TODO Auto-generated method stub

            }

            @Override
            public void disableReceiveTimeout() {
                // TODO Auto-generated method stub

            }

            @Override
            public void disableReceiveThreshold() {
                // TODO Auto-generated method stub

            }

            @Override
            public void disableReceiveFraming() {
                // TODO Auto-generated method stub

            }

            @Override
            public boolean setUARTType(final String arg0, final boolean arg1)
                    throws UnsupportedCommOperationException {
                // TODO Auto-generated method stub
                return false;
            }

            @Override
            public void setSerialPortParams(final int arg0, final int arg1,
                    final int arg2, final int arg3)
                    throws UnsupportedCommOperationException {
                // TODO Auto-generated method stub

            }

            @Override
            public void setRTS(final boolean arg0) {
                // TODO Auto-generated method stub

            }

            @Override
            public boolean setParityErrorChar(final byte arg0)
                    throws UnsupportedCommOperationException {
                // TODO Auto-generated method stub
                return false;
            }

            @Override
            public boolean setLowLatency()
                    throws UnsupportedCommOperationException {
                // TODO Auto-generated method stub
                return false;
            }

            @Override
            public void setFlowControlMode(final int arg0)
                    throws UnsupportedCommOperationException {
                // TODO Auto-generated method stub

            }

            @Override
            public boolean setEndOfInputChar(final byte arg0)
                    throws UnsupportedCommOperationException {
                // TODO Auto-generated method stub
                return false;
            }

            @Override
            public boolean setDivisor(final int arg0)
                    throws UnsupportedCommOperationException, IOException {
                // TODO Auto-generated method stub
                return false;
            }

            @Override
            public void setDTR(final boolean arg0) {
                // TODO Auto-generated method stub

            }

            @Override
            public boolean setCallOutHangup(final boolean arg0)
                    throws UnsupportedCommOperationException {
                // TODO Auto-generated method stub
                return false;
            }

            @Override
            public boolean setBaudBase(final int arg0)
                    throws UnsupportedCommOperationException, IOException {
                // TODO Auto-generated method stub
                return false;
            }

            @Override
            public void sendBreak(final int arg0) {
                // TODO Auto-generated method stub

            }

            @Override
            public void removeEventListener() {
                // TODO Auto-generated method stub

            }

            @Override
            public void notifyOnRingIndicator(final boolean arg0) {
                // TODO Auto-generated method stub

            }

            @Override
            public void notifyOnParityError(final boolean arg0) {
                // TODO Auto-generated method stub

            }

            @Override
            public void notifyOnOverrunError(final boolean arg0) {
                // TODO Auto-generated method stub

            }

            @Override
            public void notifyOnOutputEmpty(final boolean arg0) {
                // TODO Auto-generated method stub

            }

            @Override
            public void notifyOnFramingError(final boolean arg0) {
                // TODO Auto-generated method stub

            }

            @Override
            public void notifyOnDataAvailable(final boolean arg0) {
                // TODO Auto-generated method stub

            }

            @Override
            public void notifyOnDSR(final boolean arg0) {
                // TODO Auto-generated method stub

            }

            @Override
            public void notifyOnCarrierDetect(final boolean arg0) {
                // TODO Auto-generated method stub

            }

            @Override
            public void notifyOnCTS(final boolean arg0) {
                // TODO Auto-generated method stub

            }

            @Override
            public void notifyOnBreakInterrupt(final boolean arg0) {
                // TODO Auto-generated method stub

            }

            @Override
            public boolean isRTS() {
                // TODO Auto-generated method stub
                return false;
            }

            @Override
            public boolean isRI() {
                // TODO Auto-generated method stub
                return false;
            }

            @Override
            public boolean isDTR() {
                // TODO Auto-generated method stub
                return false;
            }

            @Override
            public boolean isDSR() {
                // TODO Auto-generated method stub
                return false;
            }

            @Override
            public boolean isCTS() {
                // TODO Auto-generated method stub
                return false;
            }

            @Override
            public boolean isCD() {
                // TODO Auto-generated method stub
                return false;
            }

            @Override
            public String getUARTType()
                    throws UnsupportedCommOperationException {
                // TODO Auto-generated method stub
                return null;
            }

            @Override
            public int getStopBits() {
                // TODO Auto-generated method stub
                return 0;
            }

            @Override
            public byte getParityErrorChar()
                    throws UnsupportedCommOperationException {
                // TODO Auto-generated method stub
                return 0;
            }

            @Override
            public int getParity() {
                // TODO Auto-generated method stub
                return 0;
            }

            @Override
            public boolean getLowLatency()
                    throws UnsupportedCommOperationException {
                // TODO Auto-generated method stub
                return false;
            }

            @Override
            public int getFlowControlMode() {
                // TODO Auto-generated method stub
                return 0;
            }

            @Override
            public byte getEndOfInputChar()
                    throws UnsupportedCommOperationException {
                // TODO Auto-generated method stub
                return 0;
            }

            @Override
            public int getDivisor() throws UnsupportedCommOperationException,
                    IOException {
                // TODO Auto-generated method stub
                return 0;
            }

            @Override
            public int getDataBits() {
                // TODO Auto-generated method stub
                return 0;
            }

            @Override
            public boolean getCallOutHangup()
                    throws UnsupportedCommOperationException {
                // TODO Auto-generated method stub
                return false;
            }

            @Override
            public int getBaudRate() {
                // TODO Auto-generated method stub
                return 0;
            }

            @Override
            public int getBaudBase() throws UnsupportedCommOperationException,
                    IOException {
                // TODO Auto-generated method stub
                return 0;
            }

            @Override
            public void addEventListener(final SerialPortEventListener arg0)
                    throws TooManyListenersException {
                // TODO Auto-generated method stub

            }
        };
        this.listener = listener;
        input = new PipedInputStream();
        output = new PipedOutputStream((PipedInputStream) input);
        out = new PrintStream(output);
        in = new BufferedReader(new InputStreamReader(input));
    }

    public InputStream getInputStream() {
        return input;
    }

    public OutputStream getOutputStream() {
        return output;
    }

}
